<?php


namespace app\common\model\mysql;

use app\common\enum\product\SpecType as SpecTypeEnum;
use app\common\library\helper;
use app\common\model\mysql\GoodsCategoryRel as GoodsCategoryRelModel;
use app\common\model\mysql\GoodsImage as GoodsImageModel;
use app\common\model\mysql\GoodsSku as GoodsSkuModel;
use app\common\model\mysql\GoodsSpecRel as GoodsSpecRelModel;
use app\common\model\mysql\Spec as SpecModel;
use think\model\concern\SoftDelete;
use think\model\relation\HasOne;


class Goods extends BaseModel
{
    use SoftDelete;

    protected $deleteTime = 'delete_time';

    // 设置当前模型对应的完整数据表名称
    protected $table = 'mall_goods';

    // 定义主键
    protected $pk = 'goods_id';

    // 开启自动写入时间戳字段
    protected $autoWriteTimestamp = true;

    // 模型初始化
    protected static function init()
    {
        // TODO:初始化内容
    }

    /**
     * 关联商品图片表
     * @return \think\model\relation\HasMany
     */
    public function images()
    {
        return $this->hasMany('GoodsImage', 'goods_id', 'goods_id')->order('sort');
    }

    /**
     * 关联模型：主图视频文件
     * @return HasOne
     */
    public function video(): HasOne
    {
        return $this->hasOne('DriverFile', 'id', 'video_id');
    }

    /**
     * 关联模型：主图视频封面图片文件
     * @return HasOne
     */
    public function videoCover(): HasOne
    {
        return $this->hasOne('DriverFile', 'id', 'video_cover_id');
    }

    /**
     * 商品详情：HTML实体转换回普通字符
     * @param $value
     * @return string
     */
    public function getContentAttr($value)
    {
        return htmlspecialchars_decode($value);
    }

    /**
     * 关联商品分类表
     * @return \think\model\relation\HasMany
     */
    public function category()
    {
        // ->bind(['category_id' => 'category_id'])
        return $this->hasMany('GoodsCategoryRel', 'goods_id', 'goods_id');
    }

    /**
     * 关联商品规格表
     * @return \think\model\relation\HasMany
     */
    public function skuList()
    {
        return $this->hasMany('GoodsSku');
    }

    /**
     * 关联商品规格关系表
     * @return \think\model\relation\HasMany
     */
    public function specRel()
    {
        return $this->hasMany('GoodsSpecRel');
    }

    // 列表查询
    public static function list($params)
    {
        // 分页查询
        $order = [
            'sort' => 'acs',
            'update_time' => 'desc',
            'create_time' => 'desc',
        ];

        $currentPage = $params['current'] ?? 1;
        $pageSize = $params['pageSize'] ?? 30;

        $where = [];
        // 筛选
        if (!empty($params['name'])) {
            $where[] = ['name', 'like', '%' . $params['name'] . '%'];
        }
        // 编码
        if (isset($params['no'])) {
            $where[] = ['no', 'like', '%' . $params['no'] . '%'];
        }

        if (isset($params['status']) && $params['status'] != '') {
            $where[] = ['status', '=', $params['status']];
        }

        $query = self::where($where)->order($order)->with('images')->with('images.file');
        // 查询
        $count = $query->count();
        $list = $query->page($currentPage, $pageSize)->select();

        return [
            'total' => (int)$count,
            'totalPage' => ceil($count / $pageSize),
            'current' => (int)$currentPage,
            'pageSize' => (int)$pageSize,
            'list' => $list,
        ];
    }

    /**
     * 添加商品
     * @param array $data
     * @return bool
     * @throws \cores\exception\BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function add(array $data): bool
    {
        // 创建商品数据
        $data = $this->createData($data);
        // 事务处理
        $this->transaction(function () use ($data) {
            // 添加商品 goods_id
            $this->save($data);
            // 新增商品与分类关联
            GoodsCategoryRelModel::increased((int)$this['goods_id'], $data['categoryIds']);
            // 新增商品与图片关联
            GoodsImageModel::increased((int)$this['goods_id'], $data['imagesIds']);
            // 新增商品与规格关联
            GoodsSpecRelModel::increased((int)$this['goods_id'], $data['newSpecList']);
            // 新增商品sku信息
            GoodsSkuModel::add((int)$this['goods_id'], $data['spec_type'], $data['newSkuList']);
        });
        return true;
    }

    /**
     * 编辑商品
     * @param array $data
     * @return bool
     * @throws \cores\exception\BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function edit(array $data): bool
    {
        // 创建商品数据
        $data = $this->createData($data);
        // 事务处理
        $this->transaction(function () use ($data) {
            // 更新商品
            $this->update($data);
            // 更新商品与分类关联
            GoodsCategoryRelModel::updates((int)$this['goods_id'], $data['categoryIds']);
            // 更新商品与图片关联
            GoodsImageModel::updates((int)$this['goods_id'], $data['imagesIds']);
            // 更新商品与规格关联
            GoodsSpecRelModel::updates((int)$this['goods_id'], $data['newSpecList']);
            // 更新商品sku信息
            GoodsSkuModel::edit((int)$this['goods_id'], $data['spec_type'], $data['newSkuList']);
        });
        return true;
    }

    /**
     * 创建商品数据
     * @param array $data
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \cores\exception\BaseException
     */
    private function createData(array $data): array
    {
        // 默认数据
        $data = array_merge($data, [
            'line_price' => $data['line_price'] ?? 0,
            'content' => $data['content'] ?? '',
            'newSpecList' => [],
            'newSkuList' => [],
        ]);
        // 库存总量 stock_total
        // 商品价格 最低最高
        /**
         *  商品规格 SpecTypeEnum
         *  单规格 SINGLE = 10;
         *  多规格 MULTI = 20;
         */
        if ($data['spec_type'] == SpecTypeEnum::MULTI) {
            $data['stock_total'] = GoodsSkuModel::getStockTotal($data['specData']['skuList']);
            [$data['price_min'], $data['price_max']] = GoodsSkuModel::getGoodsPrices($data['specData']['skuList']);
            [$data['line_price_min'], $data['line_price_max']] = GoodsSkuModel::getLinePrices($data['specData']['skuList']);
        } elseif ($data['spec_type'] == SpecTypeEnum::SINGLE) {
            $data['price_min'] = $data['price_max'] = $data['price'];
            $data['line_price_min'] = $data['line_price_max'] = $data['line_price'];
            $data['stock_total'] = $data['stock_num'];
        }
        // 规格和sku数据处理
        if ($data['spec_type'] == SpecTypeEnum::MULTI) {
            // 验证规格值是否合法 skuList 组合sku specList 规格组信息
            SpecModel::checkSpecData($data['specData']['specList']);
            // 生成多规格数据 (携带id)
            $data['newSpecList'] = SpecModel::getNewSpecList($data['specData']['specList']);
            // 生成skuList (携带product_sku_id)
            $data['newSkuList'] = GoodsSkuModel::getNewSkuList($data['newSpecList'], $data['specData']['skuList']);
        } elseif ($data['spec_type'] == SpecTypeEnum::SINGLE) {
            // 生成skuItem
            $data['newSkuList'] = helper::pick($data, ['price', 'line_price', 'stock_num', 'weight']);
        }
        // 单独设置折扣的配置 TODO
        $data['is_enable_grade'] == 0 && $data['is_alone_grade'] = 0;
        $aloneGradeEquity = [];
//        if ($data['is_alone_grade'] == 1) {
//            foreach ($data['alone_grade_equity'] as $key => $value) {
//                $gradeId = str_replace('grade_id:', '', $key);
//                $aloneGradeEquity[$gradeId] = $value;
//            }
//        }
        $data['alone_grade_equity'] = $aloneGradeEquity;

        return $data;
    }
}